package com.museum.service.impl.admin;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.museum.base.BaseApiService;
import com.museum.base.BaseResponse;
import com.museum.entity.DO.Permission;
import com.museum.entity.DTO.Meta;
import com.museum.entity.DTO.permission.PermissionShow;
import com.museum.mapper.AreaPermissionMapper;
import com.museum.mapper.PermissionMapper;
import com.museum.mapper.RolePermissionMapper;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;

/**
 * @Description:
 * @ClassName museum
 * @Author: 王瑞文
 * @Date: 2020/12/20 9:26
 */
@Service
public class AdminPermissionService extends BaseApiService<JSONObject> {
    @Autowired
    private AreaPermissionMapper areaPermissionMapper;
    @Autowired
    private PermissionMapper permissionMapper;
    @Autowired
    private RolePermissionMapper rolePermissionMapper;

    /**
     * 获取全部菜单信息
     *
     * @return
     */
    public BaseResponse<JSONObject> getAllPermission() {
        List<Permission> permissions = permissionMapper.selectList(new QueryWrapper<Permission>().ne("name", "个人信息").notLike("path", "super"));
        System.out.println(permissions);
        List<PermissionShow> permissionShows = queryMenu(permissions);
        if (permissionShows.size() > 0) {
            JSONObject object = new JSONObject();
            object.put("permissions", permissionShows);
            return setResultSuccess(object);

        }
        return setResultNotFound("查询不到权限菜单!");
    }

    /**
     * 根据不同角色获取不同的菜单
     *
     * @return
     */
    public BaseResponse<JSONObject> getPermission() {
        // 可以用的权限id
        //TODO getRoleID
        List<Integer> canUse = rolePermissionMapper.Permission_rolePermission(1);
        System.out.println("canUse" + canUse);
        //不可用的权限id
        //TODO getAreaNumber
        List<Integer> noUse = getNoUsePermissionIdsByAreaNumber(113);
        System.out.println("noUse" + noUse);
        return getCanUsePermissions(canUse, noUse);
    }

    public List<PermissionShow> queryMenu(List<Permission> permissionList) {
        return build2(TransformPermissionShows(permissionList));
    }

    //使用递归方法建菜单
    public List<PermissionShow> build2(List<PermissionShow> treeNodes) {
        //创建list集合，用于数据最终封装
        List<PermissionShow> trees = new ArrayList<>();
        //把所有菜单list集合遍历，得到顶层菜单 pid=0菜单，设置level是1
        for (PermissionShow treeNode : treeNodes) {
            //得到顶层菜单 pid=0菜单
            if (0 == treeNode.getParentId()) {
                //根据顶层菜单，向里面进行查询子菜单，封装到finalNode里面
                trees.add(findChildren2(treeNode, treeNodes));
            }
        }
        return trees;
    }

    //递归查找子节点
    public PermissionShow findChildren2(PermissionShow treeNode, List<PermissionShow> treeNodes) {
        //1 因为向一层菜单里面放二层菜单，二层里面还要放三层，把对象初始化
        treeNode.setChildren(new ArrayList<PermissionShow>());
        //2 遍历所有菜单list集合，进行判断比较，比较id和pid值是否相同
        for (PermissionShow node : treeNodes) {
            //判断 id和pid值是否相同

            if (treeNode.getPermissionId() == node.getParentId()) {

                //把查询出来的子菜单放到父菜单里面
                treeNode.getChildren().add(findChildren2(node, treeNodes));
            }
        }
        return treeNode;
    }

    // 递归查找PermissionID子节点 (打开按钮可用)
    public List<Integer> findIDChildren(List<Integer> treeID, Integer permissionID) {
        treeID.add(permissionID);
        List<Integer> parentIdByPermissionIds = permissionMapper.getParentIdByPermissionIds(permissionID);
        if (parentIdByPermissionIds.size() != 0) {
            for (Integer parentIdByPermissionId : parentIdByPermissionIds) {
                findIDChildren(treeID, parentIdByPermissionId);
            }
        }
        return treeID;
    }

    // 递归查找PermissionID父亲节点
    public List<Integer> findIDFather(List<Integer> treeID, Integer permissionID) {
        treeID.add(permissionID);
        Integer permissionId = permissionMapper.getParentIdByPermissionId(permissionID);

        if (permissionID != null && permissionId != 0) {
            findIDFather(treeID, permissionId);
        }
        return treeID;
    }

    /**
     * 关闭菜单
     *
     * @param permissionID
     * @return
     */
    public BaseResponse<JSONObject> closePermission(Integer permissionID) {

        //1、关闭按钮 1）关闭子ID 2）判断父亲开关状态
        List<Integer> treeChildren = new ArrayList<>();
        treeChildren = findIDChildren(treeChildren, permissionID);
        //close子节点
        for (Integer treeChild : treeChildren) {
            permissionMapper.closePermission(treeChild);
        }
        //Judge父节点还能查出来节点吗?
        List<Integer> treeFather = new ArrayList<>();
        treeFather = findIDFather(treeFather, permissionID);
        if (treeFather.size() != 0) {
            treeFather.remove(0);
            for (Integer integer : treeFather) {
                List<Integer> children = new ArrayList<>();
                children = findIDChildren(children, integer);
                if (children.size() != 0)
                    children.remove(0);
                if (children.size() == 0 || judgeIsClose(children))
                    permissionMapper.closePermission(integer);
            }
        }
        //获取关联菜单
        return setResultSuccess("操作成功！");
    }

    /**
     * 打开菜单权限
     *
     * @param permissionID
     * @return
     */
    public BaseResponse<JSONObject> openPermission(Integer permissionID) {

        List<Integer> treeC = new ArrayList<>();
        treeC = findIDChildren(treeC, permissionID);
        List<Integer> treeF = new ArrayList<>();
        treeF = findIDFather(treeF, permissionID);
        //开启子节点
        for (Integer integer : treeF) {

            permissionMapper.openPermissionByPermissionID(integer);
        }
        //开启父节点
        for (Integer integer : treeC) {
            permissionMapper.openPermissionByPermissionID(integer);
        }

        return setResultSuccess("操作成功！");
    }

    //判断是权限是否父菜单
    public boolean judgeIsClose(List<Integer> permissionIds) {
        List<Integer> canUsePermissionIDs = permissionMapper.getCanUsePermissionIDs();
        for (Integer permissionId : permissionIds) {
            for (Integer canUsePermissionID : canUsePermissionIDs) {
                if (permissionId == canUsePermissionID)
                    return false;
            }
        }
        return true;
    }

    // 封装数据
    public List<PermissionShow> TransformPermissionShows(List<Permission> permissionList) {
        List<PermissionShow> permissionShows = new ArrayList<>();

        for (Permission permission : permissionList) {
            PermissionShow permissionShow = new PermissionShow();
            BeanUtils.copyProperties(permission, permissionShow);
            permissionShow.setMeta(new Meta(permission.getIcon(), permission.getName()));
            permissionShows.add(permissionShow);
        }
        return permissionShows;
    }

    // 根据角色对应的权限ID获取权限表
    public List<Permission> getPermissionByPermissionIds(List<Integer> ids) {
        List<Permission> permissions = new ArrayList<>();
        for (Integer id : ids) {
            Permission permission = permissionMapper.selectById(id);
            if (permission != null)
                permissions.add(permission);
        }
        return permissions;
    }

    //根据地域编号查询不可用权限
    public List<Integer> getNoUsePermissionIdsByAreaNumber(Integer areaNumber) {
        return areaPermissionMapper.getNoUsePermissionIDs(areaNumber);
    }

    //根据地域编号查询可用权限
    public List<Integer> getCanUsePermissionIdsByAreaNumber(Integer areaNumber) {
        return areaPermissionMapper.getCanUsePermissionIDs(areaNumber);
    }

    //筛选出来可用权限
    public BaseResponse<JSONObject> getCanUsePermissions(List<Integer> ids, List<Integer> noUse) {
        for (Integer integer : noUse) {
            if (ids.contains(integer))
                ids.remove(integer);
        }
        List<Permission> permissions = getPermissionByPermissionIds(ids);
        if (permissions.size() == 0) {
            return setResultNotFound("无权限数据");
        }
        JSONObject object = new JSONObject();
        object.put("permissions", queryMenu(permissions));
        return setResultSuccess(object);
    }
}
